package com.leyou.order.service;

import com.leyou.auth.pojo.UserInfo;
import com.leyou.common.dto.CartDTO;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.util.IdWorker;
import com.leyou.item.pojo.Sku;
import com.leyou.order.client.AddressClient;
import com.leyou.order.client.GoodsClient;
import com.leyou.order.dto.AddressDTO;
import com.leyou.order.dto.OrderDTO;
import com.leyou.order.enums.OrderStatusEnum;
import com.leyou.order.enums.PayStateEnum;
import com.leyou.order.interceptor.UserInterceptor;
import com.leyou.order.mapper.OrderDetailMapper;
import com.leyou.order.mapper.OrderMapper;
import com.leyou.order.mapper.OrderStatusMapper;
import com.leyou.order.pojo.Order;
import com.leyou.order.pojo.OrderDetail;
import com.leyou.order.pojo.OrderStatus;
import com.leyou.order.util.PayHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import sun.rmi.runtime.Log;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderDetailMapper detailMapper;

    @Autowired
    private OrderStatusMapper statusMapper;


    @Autowired
    private IdWorker idWorker;

    @Autowired
    private GoodsClient goodsClient;

    @Autowired
    private PayHelper payHelper;

    @Transactional
    public Long createOrder(OrderDTO orderDTO) {


        //1.创建订单
            Order order = new Order();
            //1.1 订单编号  采用雪花算法
                long orderId = idWorker.nextId();
                order.setOrderId(orderId);
            //1.2 订单的基本信息
                order.setCreateTime(new Date());//创建时间
                order.setPaymentType(orderDTO.getPaymentType());//支付类型

            //1.2 用户信息
                UserInfo userInfo = UserInterceptor.getUserInfo();
                order.setUserId(userInfo.getId());//用户id
                order.setBuyerNick(userInfo.getUsername());//用户昵称
                order.setBuyerRate(false);//评论  创建订单不能评论
            //1.3 收货人信息
                AddressDTO address = AddressClient.findById(orderDTO.getAddressId());
                order.setReceiver(address.getName());
                order.setReceiverAddress(address.getAddress());
                order.setReceiverCity(address.getCity());
                order.setReceiverDistrict(address.getDistrict());
                order.setReceiverMobile(address.getPhone());
                order.setReceiverState(address.getState());
                order.setReceiverZip(address.getZipCode());
            //1.4  金额
            //1.4.1 把orderDTO中的Cart转为一个map  可以为cart的id  值为cart的num
                 Map<Long, Integer> numMap = orderDTO.getCarts().stream().collect(Collectors.toMap(CartDTO::getSkuId, CartDTO::getNum));
            //1.4.2 获得所有商品的ID 查询商品对象
                 List<Sku> skus = goodsClient.querySkuByIds(new ArrayList<>(numMap.keySet()));
            long totalPay = 0L;
            //在遍历价格时，把订单详情对象初始化了
                List<OrderDetail> details = new ArrayList<>();
                for (Sku sku : skus) {
                    totalPay +=sku.getPrice() * numMap.get(sku.getId());

                    //封装OrderDetail

                    OrderDetail detail = new OrderDetail();
                    //图片
                    detail.setImage(StringUtils.substringBefore(sku.getImages(),","));
                    //数量
                    detail.setNum(numMap.get(sku.getId()));
                    //订单编号
                    detail.setOrderId(orderId);
                    //规格参数
                    detail.setOwnSpec(sku.getOwnSpec());
                    //价格
                    detail.setPrice(sku.getPrice());
                    //商品id
                    detail.setSkuId(sku.getId());
                    //商品标题
                    detail.setTitle(sku.getTitle());
                    details.add(detail);
                }

            //总金额
                order.setTotalPay(totalPay);
            //实付金额   总金额+邮费-优惠
                order.setActualPay(totalPay + order.getPostFee() - 0);
            //把orer写入数据库   insertSelective  有选择性的新增。
                int count = orderMapper.insertSelective(order);
                if (count !=1) {
                    log.error("[创建订单] 创建订单失败，orderId:{}",orderId);
                    throw new LyException(ExceptionEnum.CREATE_ORDER_ERROR);
                }

        //2.新增订单详情
            count = detailMapper.insertList(details);
            if (count !=details.size()) {
                log.error("[创建订单] 创建订单失败，orderId:{}",orderId);
                throw new LyException(ExceptionEnum.CREATE_ORDER_ERROR);
            }
        //3.新增订单的状态
            OrderStatus orderStatus = new OrderStatus();
            orderStatus.setOrderId(orderId);
            orderStatus.setCommentTime(order.getCreateTime());
            orderStatus.setStatus(OrderStatusEnum.UN_PAY.value());

            count = statusMapper.insertSelective(orderStatus);
            if (count !=1) {
                log.error("[创建订单] 创建订单失败，orderId:{}",orderId);
                throw new LyException(ExceptionEnum.CREATE_ORDER_ERROR);
            }
        //4.修改库存数量
        List<CartDTO> cartDTOS = orderDTO.getCarts();
        goodsClient.decreaseStock(cartDTOS);
        return  orderId;
    }

    public Order queryOrdeyById(Long id) {
        Order order = orderMapper.selectByPrimaryKey(id);

        if (order == null) {
            throw  new LyException(ExceptionEnum.ORDER_NOT_FOUND);
        }

        //查询订单详情
        OrderDetail detail = new OrderDetail();
        detail.setOrderId(id);
        List<OrderDetail> detailList = detailMapper.select(detail);
        if(CollectionUtils.isEmpty(detailList)){
            throw new LyException(ExceptionEnum.ORDER_DETAIL_NOT_FOUND);
        }
        order.setOrderDetails(detailList);
        //查询订单状态
        OrderStatus orderStatus = statusMapper.selectByPrimaryKey(id);
        if (orderStatus == null) {
            throw  new LyException(ExceptionEnum.ORDER_STATUS_NOT_FOUND);
        }
        order.setOrderStatus(orderStatus);
        return  order;
    }

    public String createPayUrl(Long orderId) {

        //查询订单
        Order order = queryOrdeyById(orderId);
        //判断订单的状态  是否是未支付的状态。
        Integer status = order.getOrderStatus().getStatus();
        if(status != OrderStatusEnum.UN_PAY.value()){
                throw  new LyException(ExceptionEnum.ORDER_STATUS_ERROR);
        }


        //支付金额
        Long actualPay = order.getActualPay();
        //商品描述
        OrderDetail detail = order.getOrderDetails().get(0);
        String desc = detail.getTitle();
        String url = payHelper.createOrder(orderId, actualPay,desc);

        return url;
    }

    /**
     * 支付成功的回调业务处理方法
     * @param result
     */
    public void handleNotify(Map<String, String> result) {
        //1.数据验证
        payHelper.isSuccess(result);

        //2.签名的验证
        payHelper.isSValidSign(result);

        //3.获得实际支付的金额和定义的金额是否相同
        String totalFeeStr = result.get("total_fee");
        String tradeNo = result.get("out_trade_no");
        if (StringUtils.isEmpty(totalFeeStr) || StringUtils.isEmpty(tradeNo)) {
            throw  new LyException(ExceptionEnum.INVALID_ORDER_PARAM);
        }

        //3.1获得结果中的金额
        Long totalFee = Long.valueOf(totalFeeStr);

        //3.2获得订单中的金额
        Long orderId = Long.valueOf(tradeNo);

        Order order = orderMapper.selectByPrimaryKey(orderId);

        if (totalFee != order.getActualPay()) {
            //金额不符
            throw  new LyException(ExceptionEnum.INVALID_ORDER_PARAM);
        }

        //4.修改订单状态。
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderId(orderId);
        orderStatus.setStatus(OrderStatusEnum.PAYED.value());
        orderStatus.setPaymentTime(new Date());
        int count = statusMapper.updateByPrimaryKeySelective(orderStatus);

        if (count != 1) {
            throw  new LyException(ExceptionEnum.UPDATE_ORDER_STATUS_ERROR);
        }

        log.info("[支付回调]订单支付成功！订单编号:{},",orderId);
    }

    /**
     * 查询订单的支付状态
     * @param orderId
     * @return
     */
    public PayStateEnum queryOrdeyState(Long orderId) {

        OrderStatus orderStatus = statusMapper.selectByPrimaryKey(orderId);
        Integer status = orderStatus.getStatus();

        //如果已支付 表示真的支付了
        if(status != OrderStatusEnum.UN_PAY.value()){
            return PayStateEnum.SUCCESS;
        }

        //如果未支付  但其实不一定是未支付，有可能的异步通知失败导致数据没有接收到，所以需要去微信查询支付状态。
        return payHelper.queryPayState(orderId);

    }
}
